package com.central.post.service.serviceImp

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.central.common.entity.Authenticate
import com.central.common.enum.CommentTypeEnum
import com.central.common.enum.ResultCode
import com.central.common.feign.CommentService
import com.central.common.feign.UserService
import com.central.common.model.*
import com.central.common.service.impl.SuperServiceImpl
import com.central.post.mapper.AuthenticateMapper
import com.central.post.mq.PostSink
import com.central.post.mq.sendMessage
import com.central.post.pojo.authenticate.*
import com.central.post.service.AuthenticateService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.concurrent.CompletableFuture

/**
 * @author  fly
 * @date  2021/5/26 14:51
 * @version 1.0
 */
@Service
open class AuthenticateServiceImp : SuperServiceImpl<AuthenticateMapper, Authenticate>(), AuthenticateService {


    @Autowired
    private lateinit var commentService: CommentService

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var postSink: PostSink


    override fun publishAuthenticate(authenticatePublishDto: AuthenticatePublishDto, sysUser: SysUser): CommonResult<Boolean> =
        success(
            save(Authenticate().apply {
                BeanUtil.copyProperties(authenticatePublishDto, this)
                createBy = sysUser.id
            })
            , "发布成功")

    override fun removeAuthenticate(ids: String): CommonResult<Boolean> =
        success(
            removeByIds(ids.split(","))
        , "移除成功")

    override fun getAuthenticateIndexData(): CommonResult<AuthenticateIndexData> =
        success(
            AuthenticateIndexData().apply {
                authenticateTalentList = commentService.getCommentAllUserIds(CommentTypeEnum.AUTHENTICATE, PageVo(1, 100))?.run {
                    records.take(9).mapNotNull { getAuthenticateTalent(it) }.sortedBy { it.havaAuthenticateCount }
                }
                AuthenticateHelpList = list(KtQueryWrapper(Authenticate::class.java)
                    .eq(Authenticate::authenticateResult, 0)
                    .orderByDesc(Authenticate::createTime)).takeIf { it.isNotEmpty() }
                    ?.let {
                        AuthenticateList().apply {
                            authenticateCount = it.size.toLong()
                            authenticateListVos = it.mapNotNull { getAuthenticateListVo(it.id) }
                        }
                    } ?: AuthenticateList()
                AuthenticateResolveList = list(KtQueryWrapper(Authenticate::class.java)
                    .ne(Authenticate::authenticateResult, 0)
                    .orderByDesc(Authenticate::createTime)).takeIf { it.isNotEmpty() }
                    ?.run { mapNotNull { getAuthenticateListVo(it.id) } }
            }
        , "获取首页数据成功")

    override fun getAuthenticateDetail(id: Long, sysUser: SysUser, pageVo: PageVo): CommonResult<AuthenticateDetailVo> =
        getById(id)?.let {
            success(
                AuthenticateDetailVo().apply {
                    BeanUtil.copyProperties(it, this)
                    username = userService.selectByUserId(it.createBy)?.username
                    authenticateResult = when (it.authenticateResult) {
                        1 -> "正品"
                        2 -> "山寨"
                        else -> "鉴定中"
                    }
                    commentInfo = commentService.getCommentVoListByRelevanceId(it.id, sysUser, pageVo, CommentTypeEnum.AUTHENTICATE)
                }
            )
        } ?: failed(ResultCode.NO_CONTENT)

    override fun getAuthenticateTalentList(authenticateSearchDto: AuthenticateSearchDto, pageVo: PageVo): CommonResult<Page<AuthenticateTalentList>> =
        commentService.getCommentAllUserIds(CommentTypeEnum.AUTHENTICATE, pageVo)?.let {

            when(authenticateSearchDto.authenticateType) {
                0 -> it.records.mapNotNull { userId ->  getAuthenticateTalent(userId) }.sortedBy { it.havaAuthenticateCount }
                else -> it.records.mapNotNull { userId -> getAuthenticateTalent(userId) }
                    .filter { it.authenticateType == authenticateSearchDto.authenticateType }
                    .sortedBy { it.havaAuthenticateCount }
            }.takeIf { it.isNotEmpty() }?.run {
                success(
                    Page<AuthenticateTalentList>(it.current, it.size, size.toLong(), it.isSearchCount).apply {
                        records = this@run
                    }
                    , "获取鉴定达人成功")
            } ?: failed(ResultCode.NO_CONTENT)

        } ?: failed(ResultCode.NO_CONTENT)

    override fun searchAuthenticateList(authenticateSearchDto: AuthenticateSearchDto, pageVo: PageVo): CommonResult<Page<AuthenticateSearchListVo>> =
        page(Page(pageVo.pageNumber!!, pageVo.pageSize!!), KtQueryWrapper(Authenticate::class.java)
            .like(StrUtil.isNotBlank(authenticateSearchDto.title), Authenticate::title, authenticateSearchDto.title)
            .orderByDesc(Authenticate::createTime))
            .run {
                records.takeIf { it.isNotEmpty() }?.let {
                    success(
                        Page<AuthenticateSearchListVo>(current, size, total, isSearchCount).apply {
                            records = it.mapNotNull { AuthenticateSearchListVo().apply { BeanUtil.copyProperties(it, this) } }
                        }
                        , "获取搜索结果成功")
                } ?: failed(ResultCode.NO_CONTENT)
            }

    override fun getMyPublishAuthenticate(pageVo: PageVo, sysUser: SysUser): CommonResult<Page<AuthenticateListVo>> =
        page(Page(pageVo.pageNumber!!, pageVo.pageSize!!), KtQueryWrapper(Authenticate::class.java)
            .eq(Authenticate::createBy, sysUser.id)
            .orderByDesc(Authenticate::createTime))
            .run {
                records.takeIf { it.isNotEmpty() }?.let {
                    success(
                        Page<AuthenticateListVo>(current, size, total, isSearchCount).apply {
                            records = it.mapNotNull { getAuthenticateListVo(it.id) }
                        }
                        , "获取搜索结果成功")
                } ?: failed(ResultCode.NO_CONTENT)
            }

    override fun authenticate(authenticateDto: AuthenticateDto, sysUser: SysUser): CommonResult<Boolean> =
        commentService.getCommentByContentAndUserIdAndTypeAndRelevanceId("我认为是", sysUser.id, CommentTypeEnum.AUTHENTICATE, authenticateDto.id!!)
            ?.run { failed(ResultCode.HAVE_COMMENT) }
            ?: kotlin.run {
                CompletableFuture.runAsync { postSink.sendMessage(CommentRpcDto().apply {
                    content = when (authenticateDto.type) {
                        1 -> "我认为是 正品"
                        else -> "我认为是 山寨"
                    }
                    createBy = sysUser.id
                    relevanceId = authenticateDto.id
                    type = CommentTypeEnum.AUTHENTICATE.code
                }, null) }.join()
                success(true, "投票成功")
            }

    override fun settingAuthenticateResult(id: Long, type: Int): CommonResult<Boolean> = getById(id)?.run {
        success(
            updateById(this.apply { authenticateResult = type })
        , "设置成功")
    } ?: failed(ResultCode.NO_CONTENT)

    /**
     * 获取鉴定达人
     */
    private fun getAuthenticateTalent(userId: Long): AuthenticateTalentList? =
        userService.selectByUserId(userId)?.let {
            AuthenticateTalentList().apply {
                BeanUtil.copyProperties(it, this)
                commentService.getCommentVoListByUserId(userId, CommentTypeEnum.AUTHENTICATE)?.run {
                    getById(get(0).relevanceId)?.let {
                        haveAuthenticate = it.title
                        authenticateType = it.authenticateType
                    }
                    havaAuthenticateCount = size.toLong()

                }

            }
        }

    /**
     * 获取鉴定列表
     */
    private fun getAuthenticateListVo(id: Long): AuthenticateListVo? =
        getById(id)?.let {
            AuthenticateListVo().apply {
                BeanUtil.copyProperties(it, this)
                userService.selectByUserId(it.createBy)?.run {
                    this@apply.headImgUrl = this.headImgUrl
                }
            }
        }
}
